import { history } from 'umi';
import { getPersonInfoByToken, getIconfont } from '@/services/user';
import {} from '@/services/power';
import { queryMenuPower, getLogo, queryMenuPowerNew, getLastVisit } from '@/services/power';
import { HttpCode } from '@/utils/contacts';
import { tiledMenuToArray, findReplace, logoWEB } from '@/utils/userHelper';
import jurisdiction from '@/utils/jurisdiction'; // 问题反馈
import emitter from '#/utils/events';

const defaultState = {
  appLogo: '', // LOGO图片
  appName: '', // 记录当前应用
  currentUser: {}, // 用户信息
  isLoading: false,
  buttonPermissions: [], // 按钮权限
  permissionsCodes: [],
  menuList: [], // 当前路由列表
  menuPerMission: [], // 路由平铺
  // 菜单栏信息
  isLogo: false, // 是否可以修改logo
  menuCode: '',
  menuLoading: false,
  menuObj: {}, //根据菜单聚合
  eamGroup: [], //从menus接口获取eam分类
  curPath: '', //访问菜单的层级结构
  visit: {}, //最后一次访问记录
};

async function fetchWithCheck(apiCall) {
  try {
    const response = await apiCall();
    if (response?.statusCode !== HttpCode.SUCCESS) {
      throw new Error(response?.message || '请求失败');
    }
    return response;
  } catch (error) {
    throw error;
  }
}

const UserModel = {
  namespace: 'user',
  state: {
    ...defaultState,
  },
  effects: {
    *fetchCurrent(__, { put, select }) {
      try {
        const { appName } = yield select((_) => _.user);
        yield put({ type: 'update', payload: { isLoading: true } });
        const [
          menuPermissionsRes = {},
          menuRes = {},
          userRes = {},
          visitRes = {},
          iconRes = {},
          appLogoRes = {},
        ] = yield Promise.all([
          fetchWithCheck(queryMenuPower),
          fetchWithCheck(queryMenuPowerNew),
          fetchWithCheck(getPersonInfoByToken),
          fetchWithCheck(getLastVisit),
          fetchWithCheck(getIconfont),
          fetchWithCheck(getLogo),
        ]);
        if (
          menuPermissionsRes?.statusCode !== HttpCode.SUCCESS ||
          userRes?.statusCode !== HttpCode.SUCCESS
        ) {
          return yield put({ type: 'login/logout' });
        }
        const { userMenus } = menuPermissionsRes;
        const [permissionsList, eamGroup] = flatArr(userMenus);
        let obj = handleMenu(
          menuRes?.data,
          appName,
          { firstJump: true },
          menuRes.menuObj,
          visitRes?.data || {},
        );
        obj.menuObj = menuRes.menuObj || {};
        const { dataPersonBody } = userRes;
        yield put({
          type: 'update',
          payload: {
            isLoading: false,
            //待修改  *****选中的结算单元
            currentUser: dataPersonBody,
            buttonPermissions: permissionsList,
            ...obj,
            permissionsCodes: permissionsList.map((j) => j.menuCode),
            eamGroup,
            visit: visitRes?.data || {},
            menuPush: true,
            iconUrl: iconRes?.iconUrl,
            // appLogo: appLogoRes?.appLogo,
            appLogo: appLogoRes?.logoUrl,
          },
        });
      } catch (error) {
        // eslint-disable-next-line no-console
        console.error('请求数据失败:', error);
        yield put({
          type: 'update',
          payload: {
            isLoading: false,
            error: '请求数据失败，请稍后重试。',
          },
        });
      }
    },
    *onMeunList({ payload, successCallback }, { put, select }) {
      const { menuObj, menuPerMission } = yield select((_) => _.user);
      const menuList = menuObj[payload.id]?.children || [];
      const isLogo = menuPerMission.some((m) => m.url == logoWEB);

      yield put({
        type: 'update',
        payload: {
          menuLoading: true,
          menuList,
          menuPush: false,
          isLogo,
          appName: payload.appName,
        },
      });

      emitter.emit('onChangeMicroApp', { menuList, appName: payload.appName, appInfos: payload });
      yield delayFn();
      if (payload.url) {
        history.replace(`/${payload.url}`);
      }
      yield put({
        type: 'update',
        payload: {
          menuLoading: false,
        },
      });
      successCallback && successCallback();
    },
    *onRefreshMenu({ payload }, { put, select }) {
      const { appName } = yield select((_) => _.user);
      const menuRes = yield queryMenuPowerNew();
      let obj = handleMenu(menuRes?.data, appName, { ...payload }, menuRes.menuObj);
      yield put({
        type: 'update',
        payload: { ...obj, menuObj: menuRes.menuObj || {} },
      });
    },
    *setAppLogo(__, { put }) {
      const appLogo = yield getLogo();
      yield put({
        type: 'update',
        payload: {
          appLogo: appLogo.logoUrl,
        },
      });
    },
  },
  reducers: {
    update(state, action) {
      return {
        ...state,
        ...action.payload,
      };
    },
    clear() {
      return {
        ...defaultState,
      };
    },
  },
};
export default UserModel;

const handleMenu = (menuList = [], appName = '', payload = {}, menuObj = {}, visit = {}) => {
  let menuKey = getLocUrl();
  const menuPerMission = tiledMenuToArray(menuList);
  const replaceChildren = findReplace(menuPerMission, menuKey, payload, visit, appName);
  jurisdiction.save(menuPerMission);
  const menuItem = menuObj[replaceChildren.customApplicationId];
  return {
    menuList: menuItem?.children || [],
    menuPerMission: menuPerMission || [],
    appName: replaceChildren?.customApplicationName || '',
    isLogo: replaceChildren?.findLogo || false,
  };
};

const getLocUrl = function () {
  try {
    let dsplayMenuKey = window.location.hash.replace(/#\/saas\//g, '').replace(/#\//g, '') || '';
    if (!dsplayMenuKey) {
      return dsplayMenuKey;
    }
    let menuKey = dsplayMenuKey || '';
    let ques = menuKey.indexOf('?');
    if (ques >= 0) {
      return { menu: menuKey.substr(0, ques), menuParam: dsplayMenuKey };
    }
    return { menu: dsplayMenuKey, menuParam: dsplayMenuKey };
  } catch (error) {
    return '';
  }
};

const flatArr = function (arr, eamGroup = []) {
  let rootarr = [];
  arr.forEach((item) => {
    if (item.root) {
      rootarr.push(item.root);
    }
    if (item.root?.menupath == '/Eam/SubMenu') {
      eamGroup.push({ ...item.root, children: item.children.map((m) => m.root) });
    }
    if (item.children) {
      const [list] = flatArr(item.children, eamGroup);
      rootarr = rootarr.concat(list);
    }
  });
  return [rootarr, eamGroup];
};

// 延迟执行
const delayFn = async (delay = 100) => {
  await new Promise((resolve) => {
    setTimeout(() => {
      resolve();
    }, delay);
  });
};
